package org.vaadinpa.gui.views;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.vaadinpa.data.Planet;
import org.vaadinpa.data.PlanetaryScan;
import org.vaadinpa.data.Universe;
import org.vaadinpa.gui.AbstractView;
import org.vaadinpa.gui.VaadinPA;

import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.GridLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Layout;
import com.vaadin.ui.Panel;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
import com.vaadin.ui.themes.Reindeer;

public class UniverseView extends AbstractView {

	private static final long serialVersionUID = 1943176117161066482L;

	private static final String STYLE_BIGGEST = "biggest";
	private static final String STYLE_BIGGER = "bigger";
	private static final String STYLE_SAME = "same";
	private static final String STYLE_SMALLER = "smaller";
	private static final String STYLE_SMALLEST = "smallest";
	private static final String STYLE_OWN = "own";

	private static final int COL_POS = 0;
	private static final int COL_NAME = 1;
	private static final int COL_SCORE = 2;
	private static final int COL_COORDS = 3;
	private static final int COL_DISTANCE = 4;
	private static final int COL_SCANS = 5;

	private GridLayout grid = new GridLayout(6, 1);

	public UniverseView() {

		grid.addStyleName(Reindeer.LAYOUT_BLACK);
		grid.setWidth("100%");
		grid.setMargin(true);

		Panel p = new Panel(grid);
		p.setSizeFull();
		addComponent(p);
		setExpandRatio(p, 1);
		setSizeFull();
	}

	@Override
	public void reload() {

		grid.removeAllComponents();

		List<Planet> list = new ArrayList<Planet>(Universe.instance.values());
		Collections.sort(list, new Comparator<Planet>() {

			public int compare(Planet o1, Planet o2) {
				return o2.score - o1.score;
			}
		});

		int row = 0;
		Label pos = new Label("Pos");
		grid.addComponent(pos, COL_POS, row);

		Label name = new Label("Planet name, ruler");
		grid.addComponent(name, COL_NAME, row);

		Label score = new Label("Score");
		grid.addComponent(score, COL_SCORE, row);

		Label coords = new Label("Coords");
		grid.addComponent(coords, COL_COORDS, row);

		Label dist = new Label("Distance");
		grid.addComponent(dist, COL_DISTANCE, row);

		Label scanH = new Label("");
		grid.addComponent(scanH, COL_SCANS, row);
		row++;

		int ownscore = VaadinPA.getPlanet().score;
		for (Planet other : list) {

			pos = new Label(list.indexOf(other) + 1 + " ");
			grid.addComponent(pos); // new row

			name = new Label(other.name + ", " + other.ruler);
			if (other.equals(VaadinPA.getPlanet())) {

				name.addStyleName(STYLE_OWN);

			} else {

				double size = ownscore == 0 ? 0 : other.score / (double) ownscore;

				if (size > 1.5) {
					name.addStyleName(STYLE_BIGGEST);
				} else if (size > 1.1) {
					name.addStyleName(STYLE_BIGGER);
				} else if (size > 0.9) {
					name.addStyleName(STYLE_SAME);
				} else if (size > 0.5) {
					name.addStyleName(STYLE_SMALLER);
				} else {
					name.addStyleName(STYLE_SMALLEST);
				}
			}
			grid.addComponent(name, COL_NAME, row);

			score = new Label(other.score + "");
			grid.addComponent(score, COL_SCORE, row);

			coords = new Label(other.coords.toString());
			grid.addComponent(coords, COL_COORDS, row);

			dist = new Label(other.coords.distanceTo(VaadinPA.getPlanet().coords) + "");
			grid.addComponent(dist, COL_DISTANCE, row);

			if (other.equals(VaadinPA.getPlanet())) {
				Label scan = new Label("This is you.");
				scan.setData(other);
				grid.addComponent(scan, COL_SCANS, row);

			} else {
				Button scan = new Button("View latest scan");
				scan.setData(other);
				scan.addListener(new ShowScansListener());
				grid.addComponent(scan, COL_SCANS, row);
			}

			row++;
		}

	}

	@Override
	public String getTitle() {
		return "Players";
	}

	@SuppressWarnings("serial")
	private class ShowScansListener implements ClickListener {

		private Window w;

		public void buttonClick(ClickEvent event) {

			final Planet p = (Planet) event.getButton().getData();

			w = new Window("Scan of planet " + p.name);
			w.setModal(true);
			w.setWidth("500px");
			w.setHeight("300px");
			w.center();

			if (VaadinPA.getPlanet().scans.containsKey(p.coords)) {
				w.setContent(getScanLayout(VaadinPA.getPlanet().scans.get(p.coords)));
			} else {

				Label l = new Label("No scans of this planet on record. ");
				w.addComponent(l);
				l = new Label("Build scans at the Planet scans screen");
				w.addComponent(l);

			}

			getWindow().addWindow(w);
		}

		private Layout getScanLayout(final PlanetaryScan scan) {
			VerticalLayout l = new VerticalLayout();
			l.addStyleName(Reindeer.LAYOUT_BLACK);
			l.setSpacing(true);

			if (scan.techLevelAtScan.ordinal() < VaadinPA.getPlanet().level.ordinal()) {
				Label label = new Label("More comprehensive scanning available!");
				l.addComponent(label);
			}

			Label label = new Label(scan.getNewsReportHTML(), Label.CONTENT_XHTML);
			l.addComponent(label);
			return l;
		}
	}
}
